package ConcurrentHashMapTest;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.LongAdder;

public class WordCountTest {
    public static List<String> getList(){
        String word = null ;
        List<String> list = new ArrayList<>();
        for(int i = 0 ; i < 5 ; i++ ){
            word = WordGenerator.getWord();
            for(int j = 0 ; j <=200 ; j++ ){
               list.add(new String(word));
            }
        }
        Collections.shuffle(list);
       return list;
    }
    public static void main(String[] args) {
        WordCountHandler.list = getList();
        Map<String, LongAdder> count = WordCountHandler.count(() -> new ConcurrentHashMap<>() , //new HashMap<>(),
                (map, list) -> {
                    list.forEach(x -> {
                            /** 1. 使用 hashMap 的方式，这种方式是不行的，因为 HashMap 是非线程安全的。
                            map.computeIfAbsent(x, (key) -> {
                                return 1;
                            });
                            map.computeIfPresent(x, (key, oldValue) -> {
                                return oldValue + 1;
                            });
                             */
                            /**
                             * 2. 使用 ConcurrentHashMap ，这种方式只能保证一个方法里面是线程安全的，但是不能保证在
                             * 两个方法里面是线程安全的
                             * */

                            /**
                             * 3. 使用 ConCurrentHashMap + LongAdd 累加器的方式，可以解决这个问题
                             * */
                        LongAdder longAdder = map.computeIfAbsent(x, y -> new LongAdder());
                        longAdder.increment();
                    });
                }
        );
        Iterator<String> iterator = count.keySet().iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            System.out.println(String.format("word<%s> cnt is : %s" , next , count.get(next)));
        }
    }

}
